package cn.infozr.api.client;

import java.text.SimpleDateFormat;
import java.util.*;

import cn.infozr.api.util.MD5Util;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonInclude;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 温湿度信息上传接口客户端
 * 用于测试 https://IP:端口/ygydapi/v1/uploadHumitureInfo 接口
 */
public class HumitureInfoUploadApiClient extends BaseClient {
    

    
    /**
     * 温湿度信息数据项
     */
    public static class HumitureInfoItem {
        private String sbazqy;  // 设备安装区域：1常温 2阴凉 3冷藏
        private String cjsj;    // 采集时间 yyyy-MM-dd HH:mm:ss
        private String wd;      // 温度，如36.5，保留一位小数点
        private String sd;      // 湿度，如36.5，保留一位小数点
        
        // Getters and Setters
        public String getSbazqy() { return sbazqy; }
        public void setSbazqy(String sbazqy) { this.sbazqy = sbazqy; }
        
        public String getCjsj() { return cjsj; }
        public void setCjsj(String cjsj) { this.cjsj = cjsj; }
        
        public String getWd() { return wd; }
        public void setWd(String wd) { this.wd = wd; }
        
        public String getSd() { return sd; }
        public void setSd(String sd) { this.sd = sd; }
    }
    
    /**
     * 温湿度信息上传请求参数类
     */
    public static class HumitureInfoUploadRequest {
        private String appId;
        private String timestamp;
        private String reqId;
        private String uscc;
        private String data;
        private String sign;
        
        // 构造函数
        public HumitureInfoUploadRequest() {
            this.timestamp = String.valueOf(System.currentTimeMillis());
        }
        
        // Getters and Setters
        public String getAppId() { return appId; }
        public void setAppId(String appId) { this.appId = appId; }
        
        public String getTimestamp() { return timestamp; }
        public void setTimestamp(String timestamp) { this.timestamp = timestamp; }
        
        public String getReqId() { return reqId; }
        public void setReqId(String reqId) { this.reqId = reqId; }
        
        public String getUscc() { return uscc; }
        public void setUscc(String uscc) { this.uscc = uscc; }
        
        public String getData() { return data; }
        public void setData(String data) { this.data = data; }
        
        public String getSign() { return sign; }
        public void setSign(String sign) { this.sign = sign; }
    }
    
    /**
     * 生成数据签名
     * @param request 请求参数对象
     * @return 签名字符串
     * @throws Exception 加密异常
     */
    protected String generateSign(HumitureInfoUploadRequest request) throws Exception {
        // 按照字段名的字典序拼接参数
        TreeMap<String, String> params = new TreeMap<>();
        params.put("appId", request.getAppId());
        params.put("reqId", request.getReqId());
        params.put("timestamp", request.getTimestamp());
        params.put("uscc", request.getUscc());

        if (request.getData() != null && !request.getData().isEmpty()) {
            params.put("data", request.getData());
        }

        return cn.infozr.api.util.SM3SignatureUtil.generateSignature(params, SECRET_KEY);
    }
    
    /**
     * 调用温湿度信息上传接口
     * @param uscc 药店18位统一社会信用代码
     * @param data 温湿度信息数据列表
     * @return 接口响应结果
     * @throws Exception 网络或解析异常
     */
    public String uploadHumitureInfo(String uscc, List<HumitureInfoItem> data) throws Exception {
        // 构造请求参数
        HumitureInfoUploadRequest request = new HumitureInfoUploadRequest();
        request.setAppId(APP_ID);
        request.setTimestamp(String.valueOf(System.currentTimeMillis()));
        request.setUscc(uscc);
        if (data != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            String dataJson = objectMapper.writeValueAsString(data);
            request.setData(dataJson);
            // 传递相同的reqId到服务器，服务器会忽略本次请求 （为防止网格中断导致数据重复上传,建议该值传MD5(数据)）
            String reqId = MD5Util.getMD5(dataJson);
            request.setReqId(reqId);
        }
        
        // 生成签名
        request.setSign(generateSign(request));
        
        // 发送POST请求
        return sendPostRequest(HUMITURE_API_URL, request);
    }
    
    /**
     * 发送POST请求
     * @param url 请求地址
     * @param request 请求参数对象
     * @return 响应结果
     * @throws Exception 网络异常
     */
    protected String sendPostRequest(String url, HumitureInfoUploadRequest request) throws Exception {
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        // 设置请求方法和请求头
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json; utf-8");
        con.setRequestProperty("Accept", "application/json");
        con.setDoOutput(true);

        // 序列化请求参数，过滤空值
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String jsonInputString = objectMapper.writeValueAsString(request);
        System.out.println("请求参数: " + jsonInputString);
        
        // 发送请求
        try(OutputStream os = con.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = con.getResponseCode();
        // 读取响应
        if (responseCode == HttpURLConnection.HTTP_OK) {
            try(BufferedReader br = new BufferedReader(
                    new InputStreamReader(con.getInputStream(), "utf-8"))) {
                StringBuilder response = new StringBuilder();
                String responseLine = null;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
                return response.toString();
            }
        } else {
            // 读取错误响应
            try(BufferedReader br = new BufferedReader(
                    new InputStreamReader(con.getErrorStream(), "utf-8"))) {
                StringBuilder response = new StringBuilder();
                String responseLine = null;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
                System.err.println("错误响应: " + response.toString());
                return "{\"code\":" + responseCode + ",\"msg\":\"请求失败\"}";
            }
        }
    }

    public static void main(String[] args) {
        try {
            // 创建客户端实例
            HumitureInfoUploadApiClient client = new HumitureInfoUploadApiClient();

            // 创建温湿度数据列表
            List<HumitureInfoUploadApiClient.HumitureInfoItem> dataList = new ArrayList<>();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String currentDateTime = sdf.format(new Date());
            // 添加常温区温湿度记录
            HumitureInfoUploadApiClient.HumitureInfoItem item1 = new HumitureInfoUploadApiClient.HumitureInfoItem();
            item1.setSbazqy("1"); // 常温区
            item1.setCjsj(currentDateTime); // 采集时间
            item1.setWd("25.5"); // 温度
            item1.setSd("80.5"); // 湿度

            dataList.add(item1);

            // 添加阴凉区温湿度记录
            HumitureInfoUploadApiClient.HumitureInfoItem item2 = new HumitureInfoUploadApiClient.HumitureInfoItem();
            item2.setSbazqy("3"); // 阴凉区
            item2.setCjsj(currentDateTime);
            item2.setWd("20.0");
            item2.setSd("55.5");

            dataList.add(item2);

            // 添加冷藏区温湿度记录
            HumitureInfoUploadApiClient.HumitureInfoItem item3 = new HumitureInfoUploadApiClient.HumitureInfoItem();
            item3.setSbazqy("1"); // 冷藏区
            item3.setCjsj(currentDateTime);
            item3.setWd("28.0");
            item3.setSd("38.0");

            dataList.add(item3);



            // 上传温湿度数据
            System.out.println("正在上传温湿度信息...");
            String result = client.uploadHumitureInfo(uscc, dataList);

            // 输出结果
            System.out.println("温湿度信息上传结果: " + result);

        } catch (Exception e) {
            System.err.println("上传温湿度信息时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}